package com.orhon.smartcampus.modules.baseinfo.mutation;

import com.orhon.smartcampus.basicComponents.Result;
import com.orhon.smartcampus.modules.baseinfo.dao.SchoolcalendarDayDao;
import com.orhon.smartcampus.modules.baseinfo.dao.SchoolcalendarWeekDao;
import com.orhon.smartcampus.modules.baseinfo.dao.SemesterDao;
import com.orhon.smartcampus.modules.baseinfo.entity.SchoolcalendarDay;
import com.orhon.smartcampus.modules.baseinfo.entity.SchoolcalendarWeek;
import com.orhon.smartcampus.modules.baseinfo.entity.Semester;
import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Component
public class InitSchoolCalendarMutation implements DataFetcher {

    @Autowired
    private SemesterDao semesterDao;

    @Autowired
    private SchoolcalendarWeekDao schoolcalendarWeekDao;

    @Autowired
    private SchoolcalendarDayDao schoolcalendarDayDao;

    /**
     * 初始化校历,根据学期信息生成校历数据
     * editor : ths
     */
    @Override
    @Transactional(readOnly = false)
    public Object get(DataFetchingEnvironment environment) throws Exception {
        Integer semester_id = environment.getArgument("semester_id");
        Semester semester;
        try {
            semester = semesterDao.get(Semester.class,Long.valueOf(semester_id));
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error(500, "" + e);
        }
        try {
            DetachedCriteria d_criteria = DetachedCriteria.forClass(SchoolcalendarDay.class);
            d_criteria.add(Restrictions.eq("semester", semester));
            List<SchoolcalendarDay> days = (List<SchoolcalendarDay>) schoolcalendarDayDao.findByCriteria(d_criteria);
            days.forEach(d -> {
                try {
                    schoolcalendarDayDao.delete(d);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
            DetachedCriteria w_criteria = DetachedCriteria.forClass(SchoolcalendarWeek.class);
            w_criteria.add(Restrictions.eq("semesterId", semester.getId()));
            List<SchoolcalendarWeek> weeks = (List<SchoolcalendarWeek>) schoolcalendarWeekDao.findByCriteria(w_criteria);
            weeks.forEach(w -> {
                try {
                    schoolcalendarWeekDao.delete(w);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error(500, "" + e);
        }
        //开始日期
        Date start_date = semester.getStartAt();
        //结束日期
        Date end_date = semester.getEndAt();
        //总天数
        Integer dayCount = daysBetween(start_date, end_date);
        Long currentWeek_id = 0L;
        String currentMonth = "";
        Integer currentweek_sort = 0;
        Long dayTime = 24 * 60 * 60 * 1000L;
        for (int i = 0; i < dayCount; i++) {
            Date date = new Date(start_date.getTime() + dayTime * i);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            String month = "month_" + (calendar.get(Calendar.MONTH) + 1);
            Integer dayWeek = calendar.get(Calendar.DAY_OF_WEEK);
            //测试
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            String dateString = formatter.format(date);
            System.out.println(dateString + "---" + calendar.get(Calendar.YEAR) + "---" + month + "---" + dayWeek);
//            return;
            if (i == 0) {
                SchoolcalendarWeek week = new SchoolcalendarWeek();
                week.setMonth(month);
                week.setSemesterId(semester.getId());
                week.setYearCode(semester.getYearlyCode());
                week.setWeekSort(currentweek_sort + 1);
                week.setCreatedAt(new Date());
                try {
                    week = schoolcalendarWeekDao.save(week);
                    currentweek_sort = currentweek_sort+1;
                    currentWeek_id = week.getId();
                    currentMonth = week.getMonth();
                } catch (Exception e) {
                    e.printStackTrace();
                    return Result.error(500, "" + e);
                }
            }
            if (!month.equals(currentMonth)) {
                currentMonth = month;
                if (dayWeek != 1) {
                    SchoolcalendarWeek week ;
                    try {
                        week = schoolcalendarWeekDao.findById(currentWeek_id);
                        week.setAcrossMonth(month);
                        week.setUpdatedAt(new Date());
                        try {
                            schoolcalendarWeekDao.update(week);
                        } catch (Exception e) {
                            e.printStackTrace();
                        return Result.error(500, "" + e);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        return Result.error(500, "" + e);
                    }
                }
            }
            if (i != 0 && dayWeek == 1) {
                SchoolcalendarWeek week = new SchoolcalendarWeek();
                week.setMonth(month);
                week.setSemesterId(semester.getId());
                week.setYearCode(semester.getYearlyCode());
                week.setWeekSort(currentweek_sort + 1);
                week.setCreatedAt(new Date());
                try {
                    currentweek_sort = currentweek_sort+1;
                    week = schoolcalendarWeekDao.add(week);
                    currentWeek_id = week.getId();
                } catch (Exception e) {
                    e.printStackTrace();
                    return Result.error(500, "" + e);
                }
            }
            SchoolcalendarDay day = new SchoolcalendarDay();
            day.setSchoolId(semester.getBaseSchoolsBySchoolId().getId());
            day.setSemester(semester);
            day.setWeekNumber(dayWeek);
            day.setYearCode(semester.getYearlyCode());
            day.setDaySort(i + 1);
            day.setYear(calendar.get(Calendar.YEAR));
            SimpleDateFormat only_month = new SimpleDateFormat("MM");
            day.setMonth(only_month.format(date));
            SimpleDateFormat month_day = new SimpleDateFormat("MM-dd");
            day.setDay(month_day.format(date));
            day.setSpecificdate(date);
            String type;
            if (dayWeek==1 || dayWeek==7){
                type = "day_type_2";
            }else{
                type = "day_type_1";
            }
            day.setType(type);
            try {
                day.setSchoolcalendarWeek(schoolcalendarWeekDao.findById(currentWeek_id));
            } catch (Exception e) {
                e.printStackTrace();
                    return Result.error(500, "" + e);
            }
            day.setCreatedAt(new Date());
            try {
                schoolcalendarDayDao.add(day);
            } catch (Exception e) {
                e.printStackTrace();
                    return Result.error(500, "" + e);
            }
        }
        return Result.ok();
    }

    /**
     * 相差天数的计算
     * @param start 开始的时间
     * @param end  结束的时间
     * @return 相差天数
     * @throws ParseException
     */
    private static Integer daysBetween(Date start,Date end) throws ParseException
    {
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        start=sdf.parse(sdf.format(start));
        end=sdf.parse(sdf.format(end));
        Calendar cal = Calendar.getInstance();
        cal.setTime(start);
        long time1 = cal.getTimeInMillis();
        cal.setTime(end);
        long time2 = cal.getTimeInMillis();
        long between_days=(time2-time1)/(1000*3600*24);

        return Integer.parseInt(String.valueOf(between_days));
    }
}
